#!/usr/bin/env python3
"""Final video composition - using relative paths"""

import os, subprocess, re, sys

BASE = r'E:\集群文件夹\factory_os\short_video_real_data_pipeline\phase4b_90s_formal_sample\v22_kimi_claude_loop\full_story_douyin_video'
FFMPEG = r'D:\AI_WORKSPACE\tools\ffmpeg\ffmpeg.exe'
CLIPS = os.path.join(BASE, '05_clips')
VO = os.path.join(BASE, '02_voiceover')
VIDEO_OUT = os.path.join(BASE, '06_video', 'claude_code_self_evolving_video_workflow_douyin_v1.mp4')

SCENE_ORDER = ['title','punch','recording_fail','five_fails','ai_drift','chatgpt_fix',
               'python_render','multi_agent','log_lines','kimi_intro','score_bars',
               'v9_peak','v10_crash','v11_recovery','lesson','rollback',
               'review_portal','http_verify','summary','final_montage','end_card']

# Create concat file with relative paths
concat_file = os.path.join(CLIPS, 'concat_rel.txt')
with open(concat_file, 'w', encoding='utf-8') as f:
    for s in SCENE_ORDER:
        f.write(f"file {s}.mp4\n")

# Verify files exist
missing = []
for s in SCENE_ORDER:
    p = os.path.join(CLIPS, s + '.mp4')
    if not os.path.exists(p):
        missing.append(s)
if missing:
    print(f"Missing: {missing}")
    sys.exit(1)
print(f"All {len(SCENE_ORDER)} clips verified in {CLIPS}")

# Find audio
audio = os.path.join(VO, 'voiceover_master_fast.wav')
if not os.path.exists(audio):
    audio = os.path.join(VO, 'voiceover_master.wav')
    print(f"Using fallback audio: {audio}")
else:
    print(f"Audio: {audio}")

# Step 1: Concatenate scenes (run from clips dir)
joined = os.path.join(CLIPS, 'scenes_joined.mp4')
print("\n--- Step 1: Concatenating 21 scenes ---")
result = subprocess.run([
    FFMPEG, '-y', '-f', 'concat', '-safe', '0',
    '-i', 'concat_rel.txt',
    '-c', 'copy',
    'scenes_joined.mp4'
], cwd=CLIPS, capture_output=True, text=True, encoding='utf-8', errors='replace')

if result.returncode != 0:
    print(f"Concat failed: {result.stderr[-500:]}")
    exit(1)

size = os.path.getsize(joined) / (1024*1024) if os.path.exists(joined) else 0
print(f"Joined: {size:.1f} MB")

# Get duration
dur = subprocess.run([FFMPEG, '-i', joined], capture_output=True, text=True, encoding='utf-8', errors='replace')
m = re.search(r'Duration: (\d+):(\d+):(\d+\.\d+)', dur.stderr)
if m:
    print(f"Duration: {m.group(1)}:{m.group(2)}:{m.group(3)}")

# Step 2: Add audio
print("\n--- Step 2: Adding audio ---")
result = subprocess.run([
    FFMPEG, '-y',
    '-i', joined,
    '-i', audio,
    '-c:v', 'libx264', '-preset', 'medium', '-crf', '20',
    '-c:a', 'aac', '-b:a', '192k',
    '-pix_fmt', 'yuv420p',
    '-movflags', '+faststart',
    '-shortest',
    VIDEO_OUT
], capture_output=True, text=True, encoding='utf-8', errors='replace')

if result.returncode != 0:
    print(f"Audio add failed: {result.stderr[-500:]}")
    exit(1)

if os.path.exists(VIDEO_OUT):
    size = os.path.getsize(VIDEO_OUT) / (1024*1024)
    dur = subprocess.run([FFMPEG, '-i', VIDEO_OUT], capture_output=True, text=True, encoding='utf-8', errors='replace')
    m = re.search(r'Duration: (\d+):(\d+):(\d+\.\d+)', dur.stderr)
    print(f"\n{'='*50}")
    print(f"VIDEO COMPLETE")
    print(f"{'='*50}")
    print(f"Output: {VIDEO_OUT}")
    print(f"Size: {size:.1f} MB")
    if m:
        print(f"Duration: {m.group(1)}:{m.group(2)}:{m.group(3)}")
    print(f"{'='*50}")
else:
    print("FAILED!")

print("Done")
